package aiku.numericalcontroloa.Service.Impl;

import aiku.numericalcontroloa.Base.Utils.BaseEnum;
import aiku.numericalcontroloa.Base.Utils.HttpStatus;
import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.Mapper.*;
import aiku.numericalcontroloa.Mapper.MasterControl.MessageNotificationMapper;
import aiku.numericalcontroloa.Mapper.OrderManagement.OrderGoodsMapper;
import aiku.numericalcontroloa.Mapper.OrderManagement.OrderMapper;
import aiku.numericalcontroloa.Model.Dto.DevicesOutboundDto;
import aiku.numericalcontroloa.Model.Entity.*;
import aiku.numericalcontroloa.Model.Entity.MasterControl.MessageNotification;
import aiku.numericalcontroloa.Model.Entity.OrderManagement.Order;
import aiku.numericalcontroloa.Model.Entity.OrderManagement.OrderGoods;
import aiku.numericalcontroloa.Model.Vo.DevicesOutboundPageAdminVo;
import aiku.numericalcontroloa.Model.Vo.DevicesOutboundVo;
import aiku.numericalcontroloa.Model.Vo.OutboundPartVo;
import aiku.numericalcontroloa.common.utils.DateUtils;
import aiku.numericalcontroloa.enums.RoleEnum;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import aiku.numericalcontroloa.Service.DevicesOutboundService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 马
 * @description 针对表【devices_outbound】的数据库操作Service实现
 * @createDate 2024-03-02 15:02:35
 */
@Service
public class DevicesOutboundServiceImpl extends ServiceImpl<DevicesOutboundMapper, DevicesOutbound>
        implements DevicesOutboundService {
    @Autowired
    private RemarksMapper remarksMapper;
    @Autowired
    private DevicesOutboundMapper devicesOutboundMapper;
    @Autowired
    private DevicesMapper devicesMapper;
    @Autowired
    private DevicesReturnMapper devicesReturnMapper;
    @Autowired
    private ProductPartMapper productPartMapper;
    @Autowired
    private DevicesServiceImpl devicesService;
    @Autowired
    private ExamineServiceImpl examineService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OutboundPartMapper outboundPartMapper;
    @Autowired
    private OrderGoodsMapper orderGoodsMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private MessageNotificationMapper msgNotificationMapper;

    /**
     * 申请出库
     * 
     * @param devicesOutbound
     * @return
     */
    @Override
    public Result applyOutbound(DevicesOutbound devicesOutbound) {
        // TODO 权限还未做
        // 判断是否有这个设备
        Devices devices = devicesMapper.selectById(devicesOutbound.getDevicesId());
        if (devices == null) {
            return Result.error(201, "该设备不存在");
        }
        // 查询出库数量是否大于设备库存
        if (devices.getCount() < devicesOutbound.getCount()) {
            return Result.error(201, "库存不足");
        }
        // 判断是否是产品,如果是产品,需要查询产品的零件库存是否充足,如果不足，返回库存不足
        if (devices.getIsProduct().equals("0")) {
            // 去零件关系表查询是否存在零件,不存在直接下一步,如果存在零件,查询零件是否足够
            List<ProductPart> productPartList = productPartMapper
                    .selectList(new LambdaQueryWrapper<ProductPart>().eq(ProductPart::getDevicesId, devices.getId()));
            if (productPartList.size() > 0) {
                List<String> devicesIdList = productPartList.stream().map(ProductPart::getPartId)
                        .collect(Collectors.toList());
                Map<String, ProductPart> productPartMap = productPartList.stream()
                        .collect(Collectors.toMap(ProductPart::getPartId, Function.identity()));
                // 再通过产品id去仓库查询信息,判断库存是否足够
                List<Devices> devicesList = devicesMapper
                        .selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId, devicesIdList));
                for (Devices devs : devicesList) {
                    ProductPart part = productPartMap.get(devs.getId());
                    if (devs.getCount() < part.getNumber() * devicesOutbound.getCount()) {
                        return Result.error(201, "产品所需零件库存不足");
                    }
                }
            }
        }
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        devicesOutbound.setId(uuid);
        devicesOutbound.setStatus(1); // 0 已出库，1待审核，2审核不通过
        // 判断是否重复提交

        // 判断是否是员工借用，是员工借用
        DevicesReturn devicesReturn = new DevicesReturn();
        if (devicesOutbound.getType().equals("1")) {
            // 归还状态 (0归还，1待审核，2审核失败，3未归还)

            devicesReturn.setReturnStatus("1"); // 3是未归还
            devicesReturn.setUserId(StpUtil.getLoginId().toString());
            devicesReturnMapper.insert(devicesReturn);
            devicesReturn.setDevicesOutboundId(devicesOutbound.getId());
            devicesOutbound.setReturnId(devicesReturn.getId());
            devicesReturnMapper.updateById(devicesReturn);
        }
        // 查询当前
        String userid = StpUtil.getLoginId().toString();
        Examine examine = examineService.getExamine(userid);
        // 申请设备出库
        devicesOutbound.setReturnId(devicesReturn.getId());
        devicesOutbound.setUserId(examine.getUserId());
        devicesOutbound.setManagementId(examine.getManagementId());
        int i = devicesOutboundMapper.insert(devicesOutbound);
        return i > 0 ? Result.success("申请成功，等待审核") : Result.error(201, "申请失败");
    }

    /**
     * 管理员审核出库
     * 
     * @param devicesOutboundId
     * @param status
     * @return
     */
    @Override
    public Result adminCheckOutbound(String devicesOutboundId, Integer status) {
        // TODO 权限还未做
        // 查询出库单是否存在
        DevicesOutbound devicesOutbound = devicesOutboundMapper.selectById(devicesOutboundId);
        if (devicesOutbound == null) {
            return Result.error(201, "出库订单不存在");
        }
        // 查询设备库存是否充足
        Devices devs = devicesMapper.selectById(devicesOutbound.getDevicesId());
        if (devs.getCount() < devicesOutbound.getCount()) {
            return Result.error(201, "库存不足");
        }
        // 判断是否是产品,如果是产品,需要查询产品的零件库存是否充足,如果不足，返回库存不足
        if (devs.getIsProduct().equals("0")) {
            // 去零件关系表查询是否存在零件,不存在直接下一步,如果存在零件,查询零件是否足够
            List<ProductPart> productPartList = productPartMapper
                    .selectList(new LambdaQueryWrapper<ProductPart>().eq(ProductPart::getDevicesId, devs.getId()));
            if (productPartList.size() > 0) {
                List<String> devicesIdList = productPartList.stream().map(ProductPart::getPartId)
                        .collect(Collectors.toList());
                Map<String, ProductPart> productPartMap = productPartList.stream()
                        .collect(Collectors.toMap(ProductPart::getPartId, Function.identity()));
                // 再通过产品id去仓库查询信息,判断库存是否足够
                List<Devices> devicesList = devicesMapper
                        .selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId, devicesIdList));
                for (Devices devsk : devicesList) {
                    ProductPart part = productPartMap.get(devsk.getId());
                    if (devsk.getCount() < part.getNumber() * devicesOutbound.getCount()) {
                        return Result.error(201, "产品所需零件库存不足");
                    }
                    // 充足的话扣掉零件的库存
                    devsk.setCount(devsk.getCount() - part.getNumber());
                }
                // 批量更新库存
                devicesService.updateBatchById(devicesList);
            }
        }

        // 修改订单状态，并且修改设备库存
        Devices devices = devicesMapper.selectById(devicesOutbound.getDevicesId());
        devices.setCount(devices.getCount() - devicesOutbound.getCount());
        int i = devicesMapper.updateById(devices);
        devicesOutbound.setStatus(status);
        i += devicesOutboundMapper.updateById(devicesOutbound);
        return i > 1 ? Result.success("操作成功") : Result.error(201, "操作失败");
    }

    /**
     * 管理分页查询出库信息
     * 
     * @param page
     * @param size
     * @param status
     * @return
     */
    @Override
    public Result selectList(Integer page, Integer size, Integer status) {
        Page<DevicesOutbound> pages = new Page<>(page, size);
        LambdaQueryWrapper<DevicesOutbound> queryWrapper = new LambdaQueryWrapper<>();
        // 时间越新，排序越前
        queryWrapper.orderByDesc(DevicesOutbound::getOutboundTime);
        // TODO 权限还未做
        if (!status.equals("-1") && status != null) {
            queryWrapper.eq(DevicesOutbound::getStatus, status);
        }
        List<DevicesOutbound> records = devicesOutboundMapper.selectPage(pages, queryWrapper).getRecords();

        // 拿出设备id，查询设备信息
        List<String> devicesIdList = records.stream().map(DevicesOutbound::getDevicesId).collect(Collectors.toList());
        if (devicesIdList.isEmpty()) {
            return Result.success(new DevicesOutboundPageAdminVo());
        }
        List<Devices> devicesList = devicesMapper
                .selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId, devicesIdList));
        // 转换成map,用id当key,用设备对象为value
        Map<String, Devices> mapOne = devicesList.stream()
                .collect(Collectors.toMap(Devices::getId, devices -> devices));
        List<DevicesOutboundVo> devicesOutboundVoList = new ArrayList<>();
        for (DevicesOutbound record : records) {
            Devices devices = mapOne.get(record.getDevicesId());
            DevicesOutboundVo devicesOutboundVo = new DevicesOutboundVo();
            BeanUtils.copyProperties(devices, devicesOutboundVo);
            devicesOutboundVo.setDevicesId(devices.getId());
            BeanUtils.copyProperties(record, devicesOutboundVo);
            devicesOutboundVoList.add(devicesOutboundVo);
        }
        // 时间越新，排序越前
        devicesOutboundVoList.sort((o1, o2) -> o2.getOutboundTime().compareTo(o1.getOutboundTime()));
        DevicesOutboundPageAdminVo devicesOutboundPageAdminVo = new DevicesOutboundPageAdminVo();
        devicesOutboundPageAdminVo.setDevicesOutboundVoList(devicesOutboundVoList);
        devicesOutboundPageAdminVo.setTotal(pages.getTotal());

        return Result.success(devicesOutboundPageAdminVo);
    }

    /**
     * 通过出库订单id查询出库信息
     * 
     * @param devicesOutboundId
     * @return
     */

    @Override
    public Result selectById(String devicesOutboundId) {
        // 先查询是否存在该id
        DevicesOutbound devicesOutbound = devicesOutboundMapper.selectById(devicesOutboundId);
        if (devicesOutbound == null) {
            return Result.error("出库订单不存在");
        }
        // 查询设备信息
        Devices devices = devicesMapper.selectById(devicesOutbound.getDevicesId());
        DevicesOutboundVo devicesOutboundVo = new DevicesOutboundVo();
        BeanUtils.copyProperties(devices, devicesOutboundVo);
        BeanUtils.copyProperties(devicesOutbound, devicesOutboundVo);
        return Result.success(devicesOutboundVo);
    }

    /**
     * 用户归还设备申请
     * 
     * @param devicesReturn
     * @return
     */
    @Override
    public Result devReturn(DevicesReturn devicesReturn) {
        // TODO 权限还未做
        // 先检测是否有该订单
        DevicesReturn aReturn = devicesReturnMapper.selectById(devicesReturn.getId());
        if (aReturn == null) {
            return Result.error(201, "订单不存在");
        }
        if (aReturn.getReturnStatus().equals("0")) {
            return Result.error(201, "订单已审核通过,请勿重复提交");
        }
        if (aReturn.getReturnStatus().equals("1")) {
            return Result.error(201, "订单已在审核中,请勿重复提交");
        }
        // 修改订单状态
        devicesReturn.setReturnStatus("1"); // 待审核状态
        int i = devicesReturnMapper.updateById(devicesReturn);
        return i > 0 ? Result.success("申请成功") : Result.error(201, "申请失败");
    }

    @Override
    public Result getDevicesOutboundList(DevicesOutboundDto devicesOutboundDto) {
        if (devicesOutboundDto == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数(devicesOutboundDto is null)");
        }
        if (devicesOutboundDto.getCurrentPage() == null || devicesOutboundDto.getPageSize() == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少分页参数");
        }
        Page<DevicesOutbound> outboundPage = new Page<>(devicesOutboundDto.getCurrentPage(),
                devicesOutboundDto.getPageSize());
        // 权限判断
        User loginUser = userMapper.selectById(StpUtil.getLoginIdAsString());
        boolean role = loginUser.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString()) ||
                loginUser.getRoleId().equals(RoleEnum.ROLE_5.getCodeToString()) ||
                loginUser.getRoleId().equals(RoleEnum.ROLE_4.getCodeToString());

        // 条件查询
        LambdaQueryWrapper<DevicesOutbound> devicesOutboundLQW = new LambdaQueryWrapper<>();
        devicesOutboundLQW.orderByDesc(DevicesOutbound::getCreateTime)
                .eq(DevicesOutbound::getDeleted, 0);
        // 不为管理员或厂长或库管，查自己的借出记录
        if (!role) {
            devicesOutboundLQW.eq(DevicesOutbound::getUserId, loginUser.getId());
        }
        // 权限为管理员或厂长，根据申请人查询
        if (role && devicesOutboundDto.getUserId() != null) {
            devicesOutboundLQW.eq(DevicesOutbound::getUserId, devicesOutboundDto.getUserId());
        }
        // 根据类型查询
        if (devicesOutboundDto.getType() != null) {
            devicesOutboundLQW.eq(DevicesOutbound::getType, devicesOutboundDto.getType());
        }
        // 根据状态查询
        if (devicesOutboundDto.getStatus() != null) {
            devicesOutboundLQW.eq(DevicesOutbound::getStatus, devicesOutboundDto.getStatus());
        }
        List<DevicesOutbound> outboundList = devicesOutboundMapper.selectPage(outboundPage, devicesOutboundLQW)
                .getRecords();
        List<DevicesOutboundVo> outboundVoList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        if (outboundList.isEmpty()) {
            map.put("total", 0);
            map.put("outboundVoList", outboundVoList);
            return Result.success("查询成功", map);
        }

        // 根据申请人id查询用户表，根据审核人id查询用户表
        Set<String> userIdList = outboundList.stream().map(DevicesOutbound::getUserId).collect(Collectors.toSet());
        userIdList.addAll(outboundList.stream().map(DevicesOutbound::getManagementId).collect(Collectors.toSet()));
        List<User> userList = userMapper.selectBatchByIdWithDelete(userIdList);
        // 处理成map集合，根据userId获取user
        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        // 根据出库id查产品列表
        // 员工借出
        List<String> outboundIdList = outboundList.stream()
                .filter(outbound -> outbound.getType() != 0)
                .map(DevicesOutbound::getId)
                .collect(Collectors.toList());

        if (outboundIdList.isEmpty()) {
            outboundIdList.add("");
        }
        LambdaQueryWrapper<OutboundPart> outboundPartLQW = new LambdaQueryWrapper<>();
        outboundPartLQW.in(OutboundPart::getOutboundId, outboundIdList)
                .eq(OutboundPart::getDeleted, 0);  // 0表示未删除

        List<OutboundPart> outboundPartList = outboundPartMapper.selectList(outboundPartLQW);
        Set<String> partIdList = outboundPartList.stream().map(OutboundPart::getPartId).collect(Collectors.toSet());

        // 卖出订单
        // 根据订单id集合查订单产品列表
        // 筛选卖出订单
        List<DevicesOutbound> orderDevicesOutboundList = outboundList.stream()
                .filter(outbound -> outbound.getType() == 0)
                .collect(Collectors.toList());
        List<String> orderIdList = orderDevicesOutboundList.stream()
                .map(DevicesOutbound::getReturnId)
                .collect(Collectors.toList());
        // 根据卖出订单id获取出库订单id
        Map<String, String> orderIdOutboundIdMap = new HashMap<>();
        if (orderIdList.isEmpty()) {
            orderIdList.add("");
        } else {
            orderIdOutboundIdMap = orderDevicesOutboundList.stream()
                    .collect(Collectors.toMap(DevicesOutbound::getReturnId, DevicesOutbound::getId));
        }
        LambdaQueryWrapper<OrderGoods> orderGoodsLQW = new LambdaQueryWrapper<>();
        orderGoodsLQW.in(OrderGoods::getOrderId, orderIdList);
        List<OrderGoods> goodsList = orderGoodsMapper.selectList(orderGoodsLQW);
        Set<String> goodsIdList = goodsList.stream().map(OrderGoods::getGoodsId).collect(Collectors.toSet());
        partIdList.addAll(goodsIdList);
        // 根据产品列表查设备信息
        if (partIdList.isEmpty()) {
            partIdList.add("");
        }
        List<Devices> devicesList = devicesMapper.selectBatchByIdWithDelete(partIdList);
        Map<String, Devices> devicesMap = new HashMap<>();
        if (devicesList.size() > 0) {
            devicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, d -> devicesList.stream()
                    .filter(devices -> devices.getId().equals(d.getId()))
                    .findFirst()
                    .orElse(null)));
        }
        Map<String, List<OutboundPartVo>> outboundPartVoMap = new HashMap<>();
        for (OutboundPart outboundPart : outboundPartList) {
            Devices devices = devicesMap.get(outboundPart.getPartId());
            OutboundPartVo outboundPartVo = new OutboundPartVo();
            BeanUtils.copyProperties(outboundPart, outboundPartVo);
            outboundPartVo.setPartName(devices.getPartName());
            outboundPartVo.setIsProduct(devices.getIsProduct());
            outboundPartVo.setModel(devices.getModel());
            outboundPartVo.setPrice(devices.getPrice());
            outboundPartVo.setImage(devices.getImage());
            outboundPartVo.setCount(devices.getCount());
            outboundPartVo.setDevicesDescribe(devices.getDevicesDescribe());
            outboundPartVo.setRemark(devices.getRemark());
            if (outboundPartVoMap.containsKey(outboundPart.getOutboundId())) {
                outboundPartVoMap.get(outboundPart.getOutboundId()).add(outboundPartVo);
            } else {
                List<OutboundPartVo> outboundPartVoList = new ArrayList<>();
                outboundPartVoList.add(outboundPartVo);
                outboundPartVoMap.put(outboundPart.getOutboundId(), outboundPartVoList);
            }
        }
        for (OrderGoods orderGoods : goodsList) {
            Devices devices = devicesMap.get(orderGoods.getGoodsId());
            OutboundPartVo outboundPartVo = new OutboundPartVo();
            outboundPartVo.setOutboundId(orderIdOutboundIdMap.get(orderGoods.getOrderId()));
            outboundPartVo.setPartId(orderGoods.getGoodsId());
            outboundPartVo.setPartName(devices.getPartName());
            outboundPartVo.setIsProduct(devices.getIsProduct());
            outboundPartVo.setModel(devices.getModel());
            outboundPartVo.setPrice(devices.getPrice());
            outboundPartVo.setImage(devices.getImage());
            outboundPartVo.setCount(devices.getCount());
            outboundPartVo.setDevicesDescribe(devices.getDevicesDescribe());
            outboundPartVo.setRemark(devices.getRemark());
            outboundPartVo.setOutboundCount(orderGoods.getGoodsCount());
            outboundPartVo.setTotalPrice(orderGoods.getTotalAmount());
            if (outboundPartVoMap.containsKey(outboundPartVo.getOutboundId())) {
                outboundPartVoMap.get(outboundPartVo.getOutboundId()).add(outboundPartVo);
            } else {
                List<OutboundPartVo> outboundPartVoList = new ArrayList<>();
                outboundPartVoList.add(outboundPartVo);
                outboundPartVoMap.put(outboundPartVo.getOutboundId(), outboundPartVoList);
            }
        }

        for (DevicesOutbound outbound : outboundList) {
            User user = userMap.get(outbound.getUserId());
            DevicesOutboundVo outboundVo = new DevicesOutboundVo();
            BeanUtils.copyProperties(outbound, outboundVo);
            // 产品列表
            outboundVo.setOutboundPartList(outboundPartVoMap.get(outbound.getId()));
            // 申请人
            outboundVo.setApplicant(user.getNickName());
            // 申请时间
            outboundVo.setCreateTime(DateUtils.YMDHMSFormat(outbound.getCreateTime()));
            // 审核人
            if (outbound.getManagementId() != null) {
                User management = userMap.get(outbound.getManagementId());
                outboundVo.setManagementName(management.getNickName());
                // 审核时间
                outboundVo.setOutboundTime(DateUtils.YMDHMSFormat(outbound.getOutboundTime()));
            }
            outboundVoList.add(outboundVo);
        }

        map.put("total", outboundPage.getTotal());
        map.put("outboundVoList", outboundVoList);
        return Result.success("查询成功", map);
    }

    @Override
    public Result getDevicesOutbound(DevicesOutboundDto devicesOutboundDto) {
        if (devicesOutboundDto == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数[devicesOutboundDto为null]");
        }
        if (devicesOutboundDto.getId() == null || devicesOutboundDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数[devicesOutboundDto.id为null]");
        }
        // 查询是否有该出库信息
        DevicesOutbound devicesOutbound = devicesOutboundMapper.selectById(devicesOutboundDto.getId());
        if (devicesOutbound == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该出库信息不存在");
        }
        DevicesOutboundVo devicesOutboundVo = new DevicesOutboundVo();
        BeanUtils.copyProperties(devicesOutbound, devicesOutboundVo);
        // 查产品列表
        Set<String> partIdList;
        List<OutboundPart> outboundPartList = new ArrayList<>();
        List<OrderGoods> orderGoodsList = new ArrayList<>();
        Order order = null;
        if (devicesOutbound.getType() == 1) {
            // 员工借出
            LambdaQueryWrapper<OutboundPart> outboundPartLQW = new LambdaQueryWrapper<>();
            outboundPartLQW.eq(OutboundPart::getOutboundId, devicesOutbound.getId());
            outboundPartList = outboundPartMapper.selectList(outboundPartLQW);
            partIdList = outboundPartList.stream().map(OutboundPart::getPartId).collect(Collectors.toSet());
        } else if (devicesOutbound.getType() == 0) {
            // 卖出商品
            order = orderMapper.selectByIdWithDelete(devicesOutbound.getReturnId());
            LambdaQueryWrapper<OrderGoods> orderGoodsLQW = new LambdaQueryWrapper<>();
            orderGoodsLQW.eq(OrderGoods::getOrderId, devicesOutbound.getReturnId());
            orderGoodsList = orderGoodsMapper.selectList(orderGoodsLQW);
            partIdList = orderGoodsList.stream().map(OrderGoods::getGoodsId).collect(Collectors.toSet());
        } else {
            LambdaQueryWrapper<OutboundPart> outboundPartLQW = new LambdaQueryWrapper<>();
            outboundPartLQW.eq(OutboundPart::getOutboundId, devicesOutbound.getId());
            outboundPartList = outboundPartMapper.selectList(outboundPartLQW);
            partIdList = outboundPartList.stream().map(OutboundPart::getPartId).collect(Collectors.toSet());
        }
        // 根据产品列表查设备信息
        List<Devices> devicesList = devicesMapper.selectBatchIds(partIdList);
        Map<String, Devices> devicesMap = devicesList.stream()
                .collect(Collectors.toMap(Devices::getId, Function.identity()));
        List<OutboundPartVo> outboundPartVoList = new ArrayList<>();
        for (OutboundPart outboundPart : outboundPartList) {
            Devices devices = devicesMap.get(outboundPart.getPartId());
            OutboundPartVo outboundPartVo = new OutboundPartVo();
            BeanUtils.copyProperties(outboundPart, outboundPartVo);
            outboundPartVo.setPartName(devices.getPartName());
            outboundPartVo.setIsProduct(devices.getIsProduct());
            outboundPartVo.setModel(devices.getModel());
            outboundPartVo.setPrice(devices.getPrice());
            outboundPartVo.setImage(devices.getImage());
            outboundPartVo.setCount(devices.getCount());
            outboundPartVo.setDevicesDescribe(devices.getDevicesDescribe());
            outboundPartVo.setRemark(devices.getRemark());
            outboundPartVoList.add(outboundPartVo);
        }
        for (OrderGoods orderGoods : orderGoodsList) {
            Devices devices = devicesMap.get(orderGoods.getGoodsId());
            OutboundPartVo outboundPartVo = new OutboundPartVo();
            BeanUtils.copyProperties(orderGoods, outboundPartVo);
            outboundPartVo.setPartId(orderGoods.getGoodsId());
            outboundPartVo.setOutboundCount(orderGoods.getGoodsCount());
            outboundPartVo.setPartName(devices.getPartName());
            outboundPartVo.setIsProduct(devices.getIsProduct());
            outboundPartVo.setModel(devices.getModel());
            outboundPartVo.setPrice(devices.getPrice());
            outboundPartVo.setImage(devices.getImage());
            outboundPartVo.setCount(devices.getCount());
            outboundPartVo.setDevicesDescribe(devices.getDevicesDescribe());
            outboundPartVo.setRemark(devices.getRemark());
            outboundPartVo.setTotalPrice(orderGoods.getTotalAmount());
            outboundPartVoList.add(outboundPartVo);
        }
        devicesOutboundVo.setOutboundPartList(outboundPartVoList);

        // 查申请人
        User user = userMapper.selectById(devicesOutbound.getUserId());
        devicesOutboundVo.setApplicant(user.getNickName());
        devicesOutboundVo.setCreateTime(DateUtils.YMDHMSFormat(devicesOutbound.getCreateTime()));
        // 查审核人
        if (devicesOutbound.getManagementId() != null) {
            User management = userMapper.selectById(devicesOutbound.getManagementId());
            devicesOutboundVo.setManagementName(management.getNickName());
            devicesOutboundVo.setOutboundTime(DateUtils.YMDHMSFormat(devicesOutbound.getOutboundTime()));
        }
        // 物流信息
        if (order != null && order.getLogisticsInformation() != null) {
            devicesOutboundVo.setLogisticsInformationList(order.getLogisticsInformation().split(";"));
        }

        return Result.success("查询成功", devicesOutboundVo);
    }

    @Override
    @Transactional
    public Result deleteOutbound(DevicesOutboundDto devicesOutboundDto) {
        if (devicesOutboundDto == null || devicesOutboundDto.getId() == null || devicesOutboundDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查权限，只有管理员有权
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        if (!user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString())) {
            return new Result(HttpStatus.FORBIDDEN, "权限不足");
        }

        // 删除
        UpdateWrapper<DevicesOutbound> outboundPartUpdateWrapper = new UpdateWrapper<>();
        outboundPartUpdateWrapper.eq("id",devicesOutboundDto.getId())
                .set("deleted",1); // 设置删除状态为已删除;
        devicesOutboundMapper.update(null,outboundPartUpdateWrapper);

        return Result.success("删除成功");
    }


    @Override
    @Transactional
    public Result addDevicesOutbound(DevicesOutboundDto devicesOutboundDto) {
        if (devicesOutboundDto == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数[devicesOutboundDto为null]");
        }
        DevicesOutbound devicesOutbound = new DevicesOutbound();
        BeanUtils.copyProperties(devicesOutboundDto, devicesOutbound);
        // 申请人
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        devicesOutbound.setUserId(user.getId());
        devicesOutbound.setApplicant(user.getNickName());
        // 状态为待审核
        devicesOutbound.setStatus(1);
        devicesOutboundMapper.insert(devicesOutbound);

        // 出库设备
        for (OutboundPart outboundPart : devicesOutboundDto.getOutboundPartList()) {
            outboundPart.setId(UUID.randomUUID().toString());
            outboundPart.setOutboundId(devicesOutbound.getId());
            outboundPart.setCreateTime(new Date());
            outboundPart.setUpdateTime(new Date());
        }
        outboundPartMapper.insertBatch(devicesOutboundDto.getOutboundPartList());
        return Result.success("申请成功");
    }

    @Override
    @Transactional
    public Result updateDevicesOutbound(DevicesOutboundDto devicesOutboundDto) {
        if (devicesOutboundDto == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数[devicesOutboundDto为null]");
        }
        if (devicesOutboundDto.getId() == null || devicesOutboundDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数[devicesOutboundDto.id为null]");
        }
        // 查询是否有该出库信息
        DevicesOutbound devicesOutbound = devicesOutboundMapper.selectById(devicesOutboundDto.getId());
        if (devicesOutbound == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该出库信息不存在");
        }
        // 备注
        if (devicesOutboundDto.getRemark() != null) {
            devicesOutbound.setRemark(devicesOutboundDto.getRemark());
        }
        // 类型
        if (devicesOutboundDto.getType() != null) {
            devicesOutbound.setType(devicesOutboundDto.getType());
        }
        // 出库状态设为待审核
        devicesOutbound.setStatus(1);
        // 更新
        devicesOutboundMapper.updateById(devicesOutbound);

        if (devicesOutboundDto.getOutboundPartList() != null) {
            // 删除原来的产品列表，将新的插入
            outboundPartMapper.deleteBatchByOutboundId(devicesOutbound.getId());
            // 出库设备
            for (OutboundPart outboundPart : devicesOutboundDto.getOutboundPartList()) {
                outboundPart.setId(UUID.randomUUID().toString());
                outboundPart.setOutboundId(devicesOutbound.getId());
                outboundPart.setCreateTime(new Date());
                outboundPart.setUpdateTime(new Date());
            }
            outboundPartMapper.insertBatch(devicesOutboundDto.getOutboundPartList());
        }

        return Result.success("修改成功");
    }

    @Override
    @Transactional
    public Result examineDevicesOutbound(DevicesOutboundDto devicesOutboundDto) {
        if (devicesOutboundDto == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数[devicesOutboundDto is null]");
        }
        if (devicesOutboundDto.getId() == null || devicesOutboundDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数[devicesOutboundDto[id] is null]");
        }
        // 查询是否有该出库信息
        DevicesOutbound devicesOutbound = devicesOutboundMapper.selectById(devicesOutboundDto.getId());
        if (devicesOutbound == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该出库信息不存在");
        }

        // 一键出库
        if (devicesOutboundDto.getStatus() == 4) {
            // 库存中对应设备数量减少
            // 查询产品
            List<String> devicesIdList = new ArrayList<>();
            List<OrderGoods> orderGoodsList = new ArrayList<>();
            List<OutboundPart> outboundPartList = new ArrayList<>();
            if (devicesOutbound.getType() == 0) {
                // 卖出商品
                LambdaQueryWrapper<OrderGoods> goodsLQW = new LambdaQueryWrapper<>();
                goodsLQW.eq(OrderGoods::getOrderId, devicesOutbound.getReturnId());
                orderGoodsList = orderGoodsMapper.selectList(goodsLQW);
                devicesIdList = orderGoodsList.stream().map(OrderGoods::getGoodsId).collect(Collectors.toList());
            } else if (devicesOutbound.getType() == 1) {
                // 员工借出
                LambdaQueryWrapper<OutboundPart> outboundPartLQW = new LambdaQueryWrapper<>();
                outboundPartLQW.eq(OutboundPart::getOutboundId, devicesOutbound.getId());
                outboundPartList = outboundPartMapper.selectList(outboundPartLQW);
                devicesIdList = outboundPartList.stream().map(OutboundPart::getPartId).collect(Collectors.toList());
            } else {
                LambdaQueryWrapper<OutboundPart> outboundPartLQW = new LambdaQueryWrapper<>();
                outboundPartLQW.eq(OutboundPart::getOutboundId, devicesOutbound.getId());
                outboundPartList = outboundPartMapper.selectList(outboundPartLQW);
                devicesIdList = outboundPartList.stream().map(OutboundPart::getPartId).collect(Collectors.toList());
            }

            List<Devices> devicesList = devicesMapper.selectBatchIds(devicesIdList);
            Map<String, Devices> devicesMap = devicesList.stream()
                    .collect(Collectors.toMap(Devices::getId, d -> devicesList.stream()
                            .filter(devices -> devices.getId().equals(d.getId()))
                            .findFirst()
                            .orElse(null)));
            List<Devices> newDevicesList = new ArrayList<>();
            if (devicesOutbound.getType() == 0) {
                // 卖出商品
                for (OrderGoods orderGoods : orderGoodsList) {
                    Devices devices = devicesMap.get(orderGoods.getGoodsId());
                    float inventory = devices.getCount() - orderGoods.getGoodsCount();
                    if (inventory < 0) {
                        // 剩余库存小于0
                        return new Result(HttpStatus.BAD_REQUEST, "库存不足，无法出库");
                    }
                    devices.setCount(inventory);
                    newDevicesList.add(devices);
                }
            } else if (devicesOutbound.getType() != 0) {
                // 员工借出
                for (OutboundPart outboundPart : outboundPartList) {
                    Devices devices = devicesMap.get(outboundPart.getPartId());
                    float inventory = devices.getCount() - outboundPart.getOutboundCount();
                    if (inventory < 0) {
                        // 剩余库存小于0
                        return new Result(HttpStatus.BAD_REQUEST, "库存不足，无法出库");
                    }
                    devices.setCount(inventory);
                    newDevicesList.add(devices);
                }
                // 新增归还记录
                if (devicesOutbound.getType() == 1) {
                    DevicesReturn devicesReturn = new DevicesReturn();
                    // 出库id
                    devicesReturn.setDevicesOutboundId(devicesOutbound.getId());
                    // 申请人
                    devicesReturn.setUserId(devicesOutbound.getUserId());
                    // 归还状态设置为待申请
                    devicesReturn.setReturnStatus("3");
                    devicesReturnMapper.insert(devicesReturn);
                }
            }
            // 更新产品数量
            devicesMapper.updateCountBatchById(newDevicesList);
            // 创建消息通知
            MessageNotification msg = new MessageNotification();
            // 标题
            msg.setTitle("申请出库的产品已出库");
            // 内容
            msg.setContent("您申请出库的产品已出库");
            // 发布人为审核人
            msg.setPublisherId(StpUtil.getLoginIdAsString());
            // 接收人为申请人
            msg.setReceiverId(devicesOutbound.getUserId());
            // 关联id
            msg.setRelevanceId(devicesOutbound.getId());
            // 类型为仓库管理
            msg.setMsgType(6);
            // 子菜单为4出库管理
            msg.setSubmenu(4);
            // 状态为待处理
            msg.setStatus(0);
            msgNotificationMapper.insert(msg);
        }
        // 修改审核状态
        devicesOutbound.setStatus(devicesOutboundDto.getStatus());
        LambdaUpdateWrapper<DevicesOutbound> devicesOutboundLUW = new LambdaUpdateWrapper<>();
        devicesOutboundLUW.eq(DevicesOutbound::getId, devicesOutbound.getId())
                .set(DevicesOutbound::getStatus, devicesOutbound.getStatus());
        if (devicesOutbound.getStatus() == 0) {
            // 审核通过，添加审核人
            devicesOutboundLUW.set(DevicesOutbound::getManagementId, StpUtil.getLoginIdAsString())
                    .set(DevicesOutbound::getOutboundTime, new Date());
        }
        devicesOutboundMapper.update(null, devicesOutboundLUW);
        // 创建消息通知
        if (devicesOutbound.getStatus() == 1) {
            // 申请出库
            // 查厂长角色、管理员角色
            List<String> roleIdList = new ArrayList<>();
            roleIdList.add(RoleEnum.ROLE_1.getCodeToString());
            roleIdList.add(RoleEnum.ROLE_5.getCodeToString());
            LambdaQueryWrapper<User> userLQW = new LambdaQueryWrapper<>();
            userLQW.eq(User::getState, BaseEnum.USER_INCUMBENCY.getCodeInt())
                    .in(User::getRoleId, roleIdList);
            List<User> userList = userMapper.selectList(userLQW);
            if (!userList.isEmpty()) {
                List<MessageNotification> msgList = new ArrayList<>();
                for (User admin : userList) {
                    MessageNotification msg = new MessageNotification();
                    msg.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                    // 标题
                    msg.setTitle("有新的产品出库申请待审核");
                    // 内容
                    User user1 = userMapper.selectById(devicesOutbound.getUserId());
                    String content = user1.getNickName() + "申请产品出库";
                    msg.setContent(content);
                    // 发布人为申请人
                    msg.setPublisherId(user1.getId());
                    // 接收人为厂长，管理员
                    msg.setReceiverId(admin.getId());
                    // 关联id
                    msg.setRelevanceId(devicesOutbound.getId());
                    // 类型为仓库管理
                    msg.setMsgType(6);
                    // 子菜单为4出库管理
                    msg.setSubmenu(4);
                    // 状态为待处理
                    msg.setStatus(0);
                    msg.setCreateTime(new Date());
                    msgList.add(msg);
                }
                msgNotificationMapper.insertBatch(msgList);
            }
        }
        if (devicesOutbound.getStatus() == 0 || devicesOutbound.getStatus() == 2) {
            List<MessageNotification> msgList = new ArrayList<>();
            String status;
            if (devicesOutbound.getStatus() == 0) {
                // 审核通过
                status = "已通过";
            } else {
                // 审核失败
                status = "未通过";
            }
            MessageNotification msg = new MessageNotification();
            msg.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            // 标题
            String title = "产品出库申请" + status;
            msg.setTitle(title);
            // 内容
            String content = "您的产品出库申请" + status;
            msg.setContent(content);
            // 发布人为审核人
            msg.setPublisherId(StpUtil.getLoginIdAsString());
            // 接收人为申请人
            msg.setReceiverId(devicesOutbound.getUserId());
            // 关联id
            msg.setRelevanceId(devicesOutbound.getId());
            // 类型为仓库管理
            msg.setMsgType(6);
            // 子菜单为4出库管理
            msg.setSubmenu(4);
            // 状态为待处理
            msg.setStatus(0);
            msg.setCreateTime(new Date());
            msgList.add(msg);
            if (devicesOutbound.getStatus() == 0) {
                // 查库管
                LambdaQueryWrapper<User> userLQW = new LambdaQueryWrapper<>();
                userLQW.eq(User::getState, BaseEnum.USER_INCUMBENCY.getCodeInt())
                        .eq(User::getRoleId, RoleEnum.ROLE_4.getCodeToString());
                List<User> userList = userMapper.selectList(userLQW);
                User user1 = userMapper.selectById(devicesOutbound.getUserId());
                if (!userList.isEmpty()) {
                    for (User user : userList) {
                        MessageNotification msgNotification = new MessageNotification();
                        msgNotification.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                        // 标题
                        msgNotification.setTitle("有出库申请已通过，待出库处理");
                        // 内容
                        msgNotification.setContent(user1.getNickName() + "的出库申请已通过，待出库处理");
                        // 发布人为审核人
                        msgNotification.setPublisherId(StpUtil.getLoginIdAsString());
                        // 接收人为库管
                        msgNotification.setReceiverId(user.getNickName());
                        // 关联id
                        msgNotification.setRelevanceId(devicesOutbound.getId());
                        // 类型为仓库管理
                        msgNotification.setMsgType(6);
                        // 子菜单为4出库管理
                        msgNotification.setSubmenu(4);
                        // 状态为待处理
                        msgNotification.setStatus(0);
                        msgNotification.setCreateTime(new Date());
                        msgList.add(msgNotification);
                    }
                }
            }
            msgNotificationMapper.insertBatch(msgList);
        }
        return Result.success("修改成功");
    }
}
